/**
 * MultiThreadService
 * 
 */
package br.ufal.ic.sd.project.server.servermode;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import br.ufal.ic.sd.project.server.core.Channel;
import br.ufal.ic.sd.project.server.core.Server;
import br.ufal.ic.sd.project.server.core.TokenListener;
import br.ufal.ic.sd.project.server.core.TokenRing;
import br.ufal.ic.sd.project.server.factory.RequestFactory;
import br.ufal.ic.sd.project.server.singleton.ServerToken;
import br.ufal.ic.sd.project.server.singleton.Token;
import br.ufal.ic.sd.project.server.thread.Request;

/**
 * @author keven lenisk almeida andrade
 *
 */
public class MultiThreadService extends Server{

    	private Request objRequest;
    
	/**
	 * @constructor
	 * @param IntPort
	 * @throws IOException
	 */
	public MultiThreadService(int IntPort, String strRepository) {
	    
	    	this.objChannel  = new Channel();
		
	    	this.objChannel.setIntPort(IntPort);
		this.setStrRepository(strRepository); 
		
		try {
			this.objChannel.setObjServerSocket(new ServerSocket(this.objChannel.getIntPort()));
		} catch (IOException e) {
		    System.err.println("Ooops! System Error");
		}
		
		this.objServerTokken = ServerToken.getInstance();
		this.objServerTokken.setBooPermisson(false);
		
		this.objTokenListener = new TokenListener();
		this.objTokenListener.addEntity(this);
	}
	
	//================================================================== getters and setters ==================================================
	
	/**
	 * @return the objRequest
	 */
	public Request getObjRequest() {
	    return objRequest;
	}

	/**
	 * @param objRequest the objRequest to set
	 */
	public void setObjRequest(Request bjRequest) {
	    this.objRequest = bjRequest;
	}
	
	//================================================================== Methods ==============================================================
	
	/**
	 * Accept connections from multiple users
	 */
	@SuppressWarnings("unused")
	public void runServer() {
	    
	    int intRequisitions = 0;
	    
	    System.out.println("status:server up!");
	    System.out.println("multithread service started!");
	    
	    while(true){
		
		//set up for new client/requisition
		this.objChannel.setObjClientSocket(new Socket());
			
		    try {

			//set the connections parameters
			this.objChannel.setObjClientSocket(this.objChannel.getObjServerSocket().accept());
			this.objChannel.setObjOutputStreamOut(new ObjectOutputStream(this.objChannel.getObjClientSocket().getOutputStream()));
			this.objChannel.getObjOutputStreamOut().flush();
			this.objChannel.setObjInputStreamIn(new ObjectInputStream(this.objChannel.getObjClientSocket().getInputStream()));
			
			System.out.println("status: client connected!");
					    
			this.objRequest = RequestFactory.createThread(this);
		    
			new Thread(this.objRequest).start();
			
			//the token is passed after each 2 requisitions
			if(intRequisitions == 2){
			    
			    //pass the token up on the ring
			    TokenRing.passToken();
			    
			    //notify server that token's permssion is OFF
			    this.objTokenListener.notifyTokensOff();
			    
			    //restart the requisitions counter
			    intRequisitions = 0;
			}
			    
			this.objChannel.setObjClientSocket(null);
			
			//incrise the requisitions counter
			intRequisitions ++;
			
			
		} catch (IOException e) {
		    System.err.println("Ooops! System Error");
		}
	    }
	}

	public void stopService() {
		// TODO Auto-generated method stub
		
	}

	public void serviceSatus() {
		// TODO Auto-generated method stub
		
	}
	
	/**
	 * routine that performe the stress test
	 */
	public void testeDeCarga() {
	    
	    System.out.println("server up for strees test!");
	    System.out.println("multithread service started!");

	    while(true){
			
		try {
		    
		    this.objChannel.setObjClientSocket(this.objChannel.getObjServerSocket().accept());
		    
		    System.out.println("Client connected!");
		    
		    this.objRequest = RequestFactory.createThread(this);
		
		    new Thread(this.objRequest).start();
		    
		} catch (IOException e) {
		    System.err.println("Ooops! System Error");
		}
	   }
	}

	public void stopServer() {
	    // TODO Auto-generated method stub
	    
	}

	public void addService() {
	    // TODO Auto-generated method stub
	    
	}

	public void configureService() {
	    // TODO Auto-generated method stub
	    
	}

	public void removeService() {
	    // TODO Auto-generated method stub
	    
	}
}
